use std::sync::Arc;
use sea_orm::{ActiveModelTrait, QueryFilter, Set, TransactionTrait};
use sea_orm::ColumnTrait;
use sea_orm::{DatabaseConnection, EntityTrait};
use crate::entity::{sys_auth_authority, sys_auth_role, sys_auth_role_authority_r, sys_scheduled_task, user_auth_authority, user_auth_role};
use crate::graphql::system_graphql::{SysAuthAuthorityObject, SysAuthRoleObject, SysScheduledTaskInput, SysScheduledTaskObject, SysScheduledTaskUpdateInput};
use async_graphql::Result as GraphQLResult;
use chrono::Utc;
use futures_util::future::try_join_all;
use redis::aio::MultiplexedConnection;
use snowid::SnowID;
use tracing::warn;

// 获取所有角色
pub async fn get_roles(db: DatabaseConnection, conn: MultiplexedConnection)
                   -> GraphQLResult<Vec<SysAuthRoleObject>> {


    // 1. 获取全部角色（只获取基本信息，不包含权限）
    let roles = sys_auth_role::Entity::find()
        .all(&db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("Failed to fetch roles: {}", e)))?;

    // 2. 使用 get_role_by_id 获取每个角色的详细信息（包括权限）
    let role_objects = try_join_all(roles.into_iter().map(|role| {
        let db = db.clone();
        let conn = conn.clone();
        async move {
            // 使用 get_role_by_id 获取角色及其权限
            match get_role_by_id(db, conn, role.id).await {
                Ok(Some(role_object)) => Ok(role_object),
                Ok(None) => Err(async_graphql::Error::new("Role not found")),
                Err(e) => Err(e),
            }
        }
    })).await?;

    Ok(role_objects)
}


// 获取单个角色
pub async fn get_role_by_id(db: DatabaseConnection, conn: MultiplexedConnection, role_id: u64)
                        -> GraphQLResult<Option<SysAuthRoleObject>> {


    // 1. 先获取单个角色
    let role = sys_auth_role::Entity::find_by_id(role_id)
        .one(&db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("Failed to fetch role: {}", e)))?;

    // 如果角色不存在，直接返回 None
    let role = match role {
        Some(role) => role,
        None => return Ok(None),
    };

    // 2. 获取该角色关联的权限表记录
    let role_authority_relations = sys_auth_role_authority_r::Entity::find()
        .filter(sys_auth_role_authority_r::Column::RoleId.eq(role_id))
        .all(&db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("Failed to fetch role-authority relations: {}", e)))?;

    // 3. 从关联权限表中提取权限ID列表
    let authority_ids: Vec<u64> = role_authority_relations
        .iter()
        .map(|relation| relation.authority_id)
        .collect();

    // 4. 根据权限ID列表获取权限信息
    let authorities = if !authority_ids.is_empty() {
        sys_auth_authority::Entity::find()
            .filter(sys_auth_authority::Column::Id.is_in(authority_ids))
            .all(&db)
            .await
            .map_err(|e| async_graphql::Error::new(format!("Failed to fetch authorities: {}", e)))?
            .into_iter()
            .map(SysAuthAuthorityObject::from)
            .collect()
    } else {
        Vec::new()
    };

    // 5. 组装最终的角色对象
    let role_object = SysAuthRoleObject {
        id: role.id.to_string(),
        role_name: role.role_name,
        authorities,
        create_time: role.create_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        update_time: role.update_time.format("%Y-%m-%d %H:%M:%S").to_string(),
    };

    Ok(Some(role_object))
}

// 获取所有权限
pub async fn get_authorities(db: DatabaseConnection, conn: MultiplexedConnection)
                         -> GraphQLResult<Vec<SysAuthAuthorityObject>> {

    let authorities = sys_auth_authority::Entity::find()
        .all(&db.clone())
        .await
        .map_err(|e| async_graphql::Error::new(format!("Failed to fetch authorities: {}", e)))?
        .into_iter()
        .map(SysAuthAuthorityObject::from)
        .collect();

    Ok(authorities)
}

// 获取单个权限
pub async fn get_authority_by_id(db: DatabaseConnection, conn: MultiplexedConnection, authority_id: u64)
                             -> GraphQLResult<Option<SysAuthAuthorityObject>> {


    let authority = sys_auth_authority::Entity::find_by_id(authority_id)
        .one(&db.clone())
        .await
        .map_err(|e| async_graphql::Error::new(format!("Failed to fetch authority: {}", e)))?
        .map(SysAuthAuthorityObject::from);

    Ok(authority)
}

pub async fn create_authority(db: &DatabaseConnection, conn: &MultiplexedConnection, authority_name: String)
                          -> GraphQLResult<SysAuthAuthorityObject> {

    let id = SnowID::new(1)?.generate();


    let authority = sys_auth_authority::ActiveModel {
        id: Set(id),
        authority_name: Set(authority_name),
        create_time: Set(Utc::now().naive_utc()),
        update_time: Set(Utc::now().naive_utc()),
    };

    let authority = authority.insert(&db.clone())
        .await
        .map(|authority| SysAuthAuthorityObject {
            id: authority.id.to_string(),
            authority_name: authority.authority_name,
            create_time: authority.create_time.format("%Y-%m-%d %H:%M:%S").to_string(),
            update_time: authority.update_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        })
        .map_err(|e| async_graphql::Error::new(format!("Failed to create authority: {}", e)))?;


    Ok(authority)
}

// 创建角色
pub async fn create_role(
    db: &DatabaseConnection,
    conn: &MultiplexedConnection,
    role_name: String,
    authority_ids: Vec<String>
) -> GraphQLResult<SysAuthRoleObject> {
    // 创建角色
    let sn = SnowID::new(1)?;
    let role_id = sn.generate();
    let now = Utc::now().naive_utc();

    let role = sys_auth_role::ActiveModel {
        id: Set(role_id),
        role_name: Set(role_name),
        create_time: Set(now),
        update_time: Set(now),
    };

    let inserted_role = sys_auth_role::Entity::insert(role)
        .exec_with_returning(db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("创建角色失败: {}", e)))?;

    // 处理权限关联
    if !authority_ids.is_empty() {
        let role_authority_models = authority_ids.iter().map(|authority_id| {
            sys_auth_role_authority_r::ActiveModel {
                id: Set(sn.generate()),
                role_id: Set(role_id),
                authority_id: Set(authority_id.parse().unwrap()),
                create_time: Set(now),
                update_time: Set(now),
            }
        }).collect::<Vec<_>>();

        sys_auth_role_authority_r::Entity::insert_many(role_authority_models)
            .exec(db)
            .await
            .map_err(|e| async_graphql::Error::new(format!("关联角色权限失败: {}", e)))?;
    }

    // 获取权限信息
    let authorities = if !authority_ids.is_empty() {
        let authority_models = sys_auth_authority::Entity::find()
            .filter(sys_auth_authority::Column::Id.is_in(authority_ids))
            .all(db)
            .await
            .map_err(|e| async_graphql::Error::new(format!("获取权限信息失败: {}", e)))?;

        authority_models.into_iter().map(SysAuthAuthorityObject::from).collect()
    } else {
        vec![]
    };

    // 构建返回对象
    Ok(SysAuthRoleObject {
        id: inserted_role.id.to_string(),
        role_name: inserted_role.role_name,
        authorities,
        create_time: inserted_role.create_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        update_time: inserted_role.update_time.format("%Y-%m-%d %H:%M:%S").to_string(),
    })
}

// 删除角色
pub async fn delete_role(
    db: &DatabaseConnection,
    role_id: u64
) -> GraphQLResult<bool> {
    // 先删除角色关联的权限关系
    sys_auth_role_authority_r::Entity::delete_many()
        .filter(sys_auth_role_authority_r::Column::RoleId.eq(role_id))
        .exec(db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("删除角色权限关联失败: {}", e)))?;

    // 再删除角色本身
    let result = sys_auth_role::Entity::delete_by_id(role_id)
        .exec(db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("删除角色失败: {}", e)))?;

    // 返回是否成功删除
    Ok(result.rows_affected > 0)
}


// 删除权限
pub async fn delete_authority(
    db: &DatabaseConnection,
    authority_id: u64
) -> GraphQLResult<bool> {
    // 先删除与角色的关联关系
    sys_auth_role_authority_r::Entity::delete_many()
        .filter(sys_auth_role_authority_r::Column::AuthorityId.eq(authority_id))
        .exec(db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("删除权限角色关联失败: {}", e)))?;

    // 再删除权限本身
    let result = sys_auth_authority::Entity::delete_by_id(authority_id)
        .exec(db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("删除权限失败: {}", e)))?;

    // 返回是否成功删除
    Ok(result.rows_affected > 0)
}


// 更新角色
pub async fn update_role(
    db: &DatabaseConnection,
    conn: &MultiplexedConnection,
    id: String,
    role_name: String,
    authority_ids: Vec<String>
) -> GraphQLResult<SysAuthRoleObject> {
    // 开始事务
    let txn = db.begin().await
        .map_err(|e| async_graphql::Error::new(format!("开启事务失败: {}", e)))?;

    // 更新角色基本信息
    let now = chrono::Utc::now().naive_utc();
    let role_model = sys_auth_role::ActiveModel {
        id: Set(id.parse()?),
        role_name: Set(role_name),
        update_time: Set(now),
        ..Default::default()
    };

    let updated_role = sys_auth_role::Entity::update(role_model)
        .exec(&txn)
        .await
        .map_err(|e| { async_graphql::Error::new(format!("更新角色失败: {}", e)) })?;

    // 删除原有的权限关联
    sys_auth_role_authority_r::Entity::delete_many()
        .filter(sys_auth_role_authority_r::Column::RoleId.eq(&id))
        .exec(&txn)
        .await
        .map_err(|e| { async_graphql::Error::new(format!("删除原有角色权限关联失败: {}", e)) })?;

    let sn = SnowID::new(1)?;
    // 添加新的权限关联
    if !authority_ids.is_empty() {
        let role_authority_models = authority_ids.iter().map(|authority_id| {
            sys_auth_role_authority_r::ActiveModel {
                id: Set(sn.generate()),
                role_id: Set(id.parse().unwrap()),
                authority_id: Set(authority_id.parse().unwrap()),
                create_time: Set(now),
                update_time: Set(now),
            }
        }).collect::<Vec<_>>();

        warn!("关联的角色权限关系：{:?}", role_authority_models);

        sys_auth_role_authority_r::Entity::insert_many(role_authority_models)
            .exec(&txn)
            .await
            .map_err(|e| { async_graphql::Error::new(format!("关联新角色权限失败: {}", e)) })?;
    }

    // 获取权限信息
    let authorities = if !authority_ids.is_empty() {
        let authority_models = sys_auth_authority::Entity::find()
            .filter(sys_auth_authority::Column::Id.is_in(
                authority_ids.iter().map(|id| id.parse::<u64>().unwrap()).collect::<Vec<u64>>()
            ))
            .all(&txn)
            .await
            .map_err(|e| { async_graphql::Error::new(format!("获取权限信息失败: {}", e)) })?;

        authority_models.into_iter().map(SysAuthAuthorityObject::from).collect()
    } else {
        vec![]
    };

    // 提交事务
    txn.commit().await
        .map_err(|e| async_graphql::Error::new(format!("提交事务失败: {}", e)))?;

    // 构建返回对象
    Ok(SysAuthRoleObject {
        id: updated_role.id.to_string(),
        role_name: updated_role.role_name,
        authorities,
        create_time: updated_role.create_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        update_time: updated_role.update_time.format("%Y-%m-%d %H:%M:%S").to_string(),
    })
}


// 用户绑定权限
pub async fn bind_authority_to_user(
    db: &DatabaseConnection,
    user_id: String,
    authority_ids: Vec<String>
) -> GraphQLResult<bool> {

    // 添加新的权限关联
    if !authority_ids.is_empty() {

        // 获取当前时间
        let now = chrono::Utc::now().naive_utc();

        // 删除用户现有的权限关联
        user_auth_authority::Entity::delete_many()
            .filter(user_auth_authority::Column::UserId.eq(&user_id))
            .exec(db)
            .await
            .map_err(|e| async_graphql::Error::new(format!("删除用户原有权限关联失败: {}", e)))?;


        for authority_id in authority_ids.iter() {
            let existing_authority = sys_auth_authority::Entity::find()
                .filter(sys_auth_authority::Column::Id.eq(authority_id.clone()))
                .one(db)
                .await
                .map_err(|e| async_graphql::Error::new(format!("查询权限信息失败: {}", e)))?;

            let authority = match existing_authority {
                Some(auth) => auth,
                None => return Err(async_graphql::Error::new(format!("权限不存在: {}", authority_id))),
            };
            let user_authority_model = user_auth_authority::ActiveModel {
                id: Set(SnowID::new(1)?.generate()),
                user_id: Set(user_id.parse()?),
                name: Set(authority.authority_name),
                authority_id: Set(authority.id),
                create_time: Set(now),
                update_time: Set(now),
            };

            user_auth_authority::Entity::insert(user_authority_model)
                .exec(db)
                .await
                .map_err(|e| async_graphql::Error::new(format!("绑定用户权限失败: {}", e)))?;
        }

    }

    Ok(true)
}


// 用户绑定角色
pub async fn bind_role_to_user(
    db: &DatabaseConnection,
    user_id: String,
    role_ids: Vec<String>
) -> GraphQLResult<bool> {

    // 如果角色ID列表不为空，先验证角色是否存在
    if !role_ids.is_empty() {

        // 获取当前时间
        let now = chrono::Utc::now().naive_utc();
        // 删除用户现有的权限关联
        user_auth_role::Entity::delete_many()
            .filter(user_auth_authority::Column::UserId.eq(&user_id))
            .exec(db)
            .await
            .map_err(|e| async_graphql::Error::new(format!("删除用户原有角色关联失败: {}", e)))?;

        // 添加新的权限关联
        for role_id in role_ids.iter() {
            let existing_role = sys_auth_role::Entity::find()
                .filter(sys_auth_role::Column::Id.eq(role_id.clone()))
                .one(db)
                .await
                .map_err(|e| async_graphql::Error::new(format!("查询角色信息失败: {}", e)))?;

            let role = match existing_role {
                Some(auth) => auth,
                None => return Err(async_graphql::Error::new(format!("角色不存在: {}", role_id))),
            };
            let user_role_model = user_auth_role::ActiveModel {
                id: Set(SnowID::new(1)?.generate()),
                user_id: Set(user_id.parse()?),
                name: Set(role.role_name),
                role_id: Set(role.id),
                create_time: Set(now),
                update_time: Set(now),
            };

            user_auth_role::Entity::insert(user_role_model)
                .exec(db)
                .await
                .map_err(|e| async_graphql::Error::new(format!("绑定用角色限失败: {}", e)))?;
        }
    }

    Ok(true)
}



pub async fn create_scheduled_task(
    db: &DatabaseConnection,
    conn: &MultiplexedConnection,
    input: SysScheduledTaskInput
) -> GraphQLResult<SysScheduledTaskObject> {
    let id = SnowID::new(1)?.generate();
    let now = Utc::now().naive_utc();

    // 解析时间
    let next_run_time = chrono::NaiveDateTime::parse_from_str(&input.next_run_time, "%Y-%m-%d %H:%M:%S")
        .map_err(|e| async_graphql::Error::new(format!("时间格式错误: {}", e)))?;

    let last_run_time = if let Some(time_str) = input.last_run_time {
        Some(chrono::NaiveDateTime::parse_from_str(&time_str, "%Y-%m-%d %H:%M:%S")
            .map_err(|e| async_graphql::Error::new(format!("时间格式错误: {}", e)))?)
    } else {
        None
    };

    let task = sys_scheduled_task::ActiveModel {
        id: Set(id),
        create_time: Set(now),
        update_time: Set(now),
        task_name: Set(input.task_name),
        task_type: Set(input.task_type),
        cron_expression: Set(input.cron_expression),
        status: Set(input.status),
        next_run_time: Set(next_run_time),
        last_run_time: Set(last_run_time),
        retry_count: Set(0), // 新任务重试次数为0
        max_retries: Set(input.max_retries),
        shard_key: Set(input.shard_key),
        task_parameter: Set(input.task_parameter),
    };

    let inserted_task = task.insert(db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("创建定时任务失败: {}", e)))?;

    // 构建返回对象
    Ok(SysScheduledTaskObject {
        id: inserted_task.id.to_string(),
        create_time: inserted_task.create_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        update_time: inserted_task.update_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        task_name: inserted_task.task_name,
        task_type: inserted_task.task_type,
        cron_expression: inserted_task.cron_expression,
        status: inserted_task.status,
        next_run_time: inserted_task.next_run_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        last_run_time: inserted_task.last_run_time.map(|t| t.format("%Y-%m-%d %H:%M:%S").to_string()),
        retry_count: inserted_task.retry_count,
        max_retries: inserted_task.max_retries,
        shard_key: inserted_task.shard_key,
        task_parameter: inserted_task.task_parameter,
    })
}



// 获取所有定时任务
pub async fn get_scheduled_tasks(
    db: DatabaseConnection,
    _conn: MultiplexedConnection
) -> GraphQLResult<Vec<SysScheduledTaskObject>> {
    let tasks = sys_scheduled_task::Entity::find()
        .all(&db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("获取定时任务失败: {}", e)))?
        .into_iter()
        .map(|task| SysScheduledTaskObject {
            id: task.id.to_string(),
            create_time: task.create_time.format("%Y-%m-%d %H:%M:%S").to_string(),
            update_time: task.update_time.format("%Y-%m-%d %H:%M:%S").to_string(),
            task_name: task.task_name,
            task_type: task.task_type,
            cron_expression: task.cron_expression,
            status: task.status,
            next_run_time: task.next_run_time.format("%Y-%m-%d %H:%M:%S").to_string(),
            last_run_time: task.last_run_time.map(|t| t.format("%Y-%m-%d %H:%M:%S").to_string()),
            retry_count: task.retry_count,
            max_retries: task.max_retries,
            shard_key: task.shard_key,
            task_parameter: task.task_parameter,
        })
        .collect();

    Ok(tasks)
}

// 根据ID获取定时任务
pub async fn get_scheduled_task_by_id(
    db: DatabaseConnection,
    _conn: MultiplexedConnection,
    task_id: u64
) -> GraphQLResult<Option<SysScheduledTaskObject>> {
    let task = sys_scheduled_task::Entity::find_by_id(task_id)
        .one(&db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("获取定时任务失败: {}", e)))?
        .map(|task| SysScheduledTaskObject {
            id: task.id.to_string(),
            create_time: task.create_time.format("%Y-%m-%d %H:%M:%S").to_string(),
            update_time: task.update_time.format("%Y-%m-%d %H:%M:%S").to_string(),
            task_name: task.task_name,
            task_type: task.task_type,
            cron_expression: task.cron_expression,
            status: task.status,
            next_run_time: task.next_run_time.format("%Y-%m-%d %H:%M:%S").to_string(),
            last_run_time: task.last_run_time.map(|t| t.format("%Y-%m-%d %H:%M:%S").to_string()),
            retry_count: task.retry_count,
            max_retries: task.max_retries,
            shard_key: task.shard_key,
            task_parameter: task.task_parameter,
        });

    Ok(task)
}


pub async fn delete_scheduled_task(
    db: &DatabaseConnection,
    task_id: u64
) -> GraphQLResult<bool> {
    let result = sys_scheduled_task::Entity::delete_by_id(task_id)
        .exec(db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("删除定时任务失败: {}", e)))?;

    // 返回是否成功删除
    Ok(result.rows_affected > 0)
}



// 更新定时任务
pub async fn update_scheduled_task(
    db: &DatabaseConnection,
    conn: &MultiplexedConnection,
    input: SysScheduledTaskUpdateInput
) -> GraphQLResult<SysScheduledTaskObject> {
    // 解析时间
    let next_run_time = chrono::NaiveDateTime::parse_from_str(&input.next_run_time, "%Y-%m-%d %H:%M:%S")
        .map_err(|e| async_graphql::Error::new(format!("时间格式错误: {}", e)))?;

    let last_run_time = if let Some(time_str) = input.last_run_time {
        Some(chrono::NaiveDateTime::parse_from_str(&time_str, "%Y-%m-%d %H:%M:%S")
            .map_err(|e| async_graphql::Error::new(format!("时间格式错误: {}", e)))?)
    } else {
        None
    };

    // 更新定时任务
    let now = Utc::now().naive_utc();
    let task_model = sys_scheduled_task::ActiveModel {
        id: Set(input.id.parse()?),
        task_name: Set(input.task_name),
        task_type: Set(input.task_type),
        cron_expression: Set(input.cron_expression),
        status: Set(input.status),
        next_run_time: Set(next_run_time),
        last_run_time: Set(last_run_time),
        max_retries: Set(input.max_retries),
        shard_key: Set(input.shard_key),
        task_parameter: Set(input.task_parameter),
        update_time: Set(now),
        ..Default::default() // 保留其他字段不变
    };

    let updated_task = sys_scheduled_task::Entity::update(task_model)
        .exec(db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("更新定时任务失败: {}", e)))?;

    // 构建返回对象
    Ok(SysScheduledTaskObject {
        id: updated_task.id.to_string(),
        create_time: updated_task.create_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        update_time: updated_task.update_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        task_name: updated_task.task_name,
        task_type: updated_task.task_type,
        cron_expression: updated_task.cron_expression,
        status: updated_task.status,
        next_run_time: updated_task.next_run_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        last_run_time: updated_task.last_run_time.map(|t| t.format("%Y-%m-%d %H:%M:%S").to_string()),
        retry_count: updated_task.retry_count,
        max_retries: updated_task.max_retries,
        shard_key: updated_task.shard_key,
        task_parameter: updated_task.task_parameter,
    })
}

// 注册订单超时取消任务
pub async fn register_order_timeout_task(db: &DatabaseConnection) -> GraphQLResult<()> {
    let now = chrono::Utc::now().naive_utc();

    // 检查任务是否已存在
    let existing_task = sys_scheduled_task::Entity::find()
        .filter(sys_scheduled_task::Column::TaskName.eq("order_timeout_cancellation"))
        .one(db)
        .await
        .map_err(|e| async_graphql::Error::new(format!("查询任务失败: {}", e)))?;

    if existing_task.is_none() {
        // 创建任务模型
        let task_model = sys_scheduled_task::ActiveModel {
            id: Set(SnowID::new(1)?.generate()),
            create_time: Set(now),
            update_time: Set(now),
            task_name: Set("order_timeout_cancellation".to_string()),
            task_type: Set("cron".to_string()),
            cron_expression: Set(Some("0 */10 * * * *".to_string())), // 每10分钟执行一次
            status: Set("active".to_string()),
            next_run_time: Set(now),
            last_run_time: Set(None),
            retry_count: Set(0),
            max_retries: Set(3),
            shard_key: Set(None),
            task_parameter: Set(Some(r#"{"timeout_minutes": 30}"#.to_string())),
        };

        sys_scheduled_task::Entity::insert(task_model)
            .exec(db)
            .await
            .map_err(|e| async_graphql::Error::new(format!("创建任务失败: {}", e)))?;
    }

    Ok(())
}